home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / drivers / airbustr.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  21KB  |  835 lines

  1. /***************************************************************************
  2.  
  3.                                 Air Buster
  4.                             (C) 1990  Kaneko
  5.  
  6.                     driver by Luca Elia (eliavit@unina.it)
  7.  
  8. CPU   : Z-80 x 3
  9. SOUND : YM2203C        M6295
  10. OSC.  : 12.000MHz    16.000MHz
  11.  
  12.                     Interesting routines (main cpu)
  13.                     -------------------------------
  14.  
  15. fd-fe    address of int: 0x38    (must alternate? see e600/1)
  16. ff-100    address of int: 0x16
  17. 66        print "sub cpu caused nmi" and die!
  18.  
  19. 7        after tests
  20.  
  21. 1497    print string following call: (char)*,0. program continues after 0.
  22.         base addr = c300 + HL & 08ff, DE=xy , BC=dxdy
  23.         +0<-(e61b)    +100<-D    +200<-E    +300<-char    +400<-(e61c)
  24.  
  25. 1642    A<- buttons status (bits 0&1)
  26.  
  27.                     Interesting locations (main cpu)
  28.                     --------------------------------
  29.  
  30. 2907    table of routines (f150 index = 1-3f, copied to e612)
  31.         e60e<-address of routine, f150<-0. e60e is used until f150!=0
  32.  
  33.     1:    2bf4    service mode                                next
  34.  
  35.     2:    2d33    3:    16bd        4:    2dcb        5:    2fcf
  36.     6:    3262    7:    32b8
  37.  
  38.     8:    335d>    print gfx/color test page                    next
  39.     9:    33c0>    handle the above page
  40.  
  41.     a:    29c6        b:    2a24        c:    16ce
  42.  
  43.     d:    3e7e>    *
  44.     e:    3ec5>    print "Sub Cpu / Ram Error"; **
  45.     f:    3e17>    print "Coin error"; **
  46.     10:    3528>    print (c) notice, not shown                    next
  47.     11:    3730>    show (c) notice, wait 0x100 calls            next
  48.  
  49.     12:        9658    13:    97c3        14:    a9fa        15:    aa6e
  50.     16-19:    2985    1a:    9c2e        1b:    9ffa        1c:    29c6
  51.  
  52.     1d:    2988>    *
  53.  
  54.     1e:    a2c4        1f:    a31a        20:    a32f        21:    a344
  55.     22:    a359        23:    a36e        24:    a383        25:    a398
  56.     26:    a3ad        27:    a3c2        28:    a3d7        29:    a3f1
  57.     2a:    a40e        2b:    a4e5        2c:    a69d        2d:    adb8
  58.     2e:    ade9        2f:    2b8b        30:    a823
  59.  
  60.     31:    3d17>    print "warm up, wait few mins. secs left: 00"    next
  61.     32:    3dc0>    pause (e624 counter).e626                        next
  62.  
  63.     33:    96b4        34:    97ad
  64.  
  65.     35-3f:    3e7e>    *
  66.  
  67. *    Print "Command Error [$xx]" where xx is last routine index (e612)
  68. **    ld (0000h),A (??) ; loop
  69.  
  70. 3cd7    hiscores table (0x40 bytes, copied to e160)
  71.         Try entering TERU as your name :)
  72.  
  73. 7fff    country code: 0 <-> Japan; else World
  74.  
  75. e615    rank:    0-easy    1-normal    2-hard    3-hardest
  76. e624    sound code during sound test
  77.  
  78. -- Shared RAM --
  79.  
  80. f148<-    sound code (copied from e624)
  81. f14a->    read on nmi routine. main cpu writes the value and writes to port 02
  82. f150<-    index of table of routines at 2907
  83.  
  84. ----------------
  85.  
  86.  
  87.  
  88.  
  89.  
  90.                     Interesting routines (sub cpu)
  91.                     -------------------------------
  92.  
  93. 491        copy palette data    d000<-f200(a0)    d200<-f300(a0)    d400<-f400(200)
  94.  
  95. 61c        f150<-A        f151<-A    (routine index of main cpu!)
  96.         if dsw1-2 active, it does nothing (?!)
  97.  
  98. c8c        c000-c7ff<-0    c800-cfff<-0    f600<-f200(400)
  99. 1750    copies 10 lines of 20 bytes from 289e to f800
  100.  
  101. 22cd    copy 0x100 bytes
  102. 22cf    copy 0x0FF bytes
  103. 238d    copy 0x0A0 bytes
  104.  
  105.                     Interesting locations (sub cpu)
  106.                     --------------------------------
  107.  
  108. fd-fe    address of int: 0x36e    (same as 38)
  109. ff-100    address of int: 0x4b0
  110.  
  111. -- Shared RAM --
  112.  
  113. f000    credits
  114.  
  115. f001/d<-IN 24 (Service)
  116. f00e<-    bank
  117. f002<-    dsw1 (cpl'd)
  118. f003<-    dsw2 (cpl'd)
  119. f004<-    IN 20 (cpl'd) (player 1)
  120. f005<-    IN 22 (cpl'd) (player 2)
  121. f006<-    start lives: dsw-2 & 0x30 index; values: 3,4,5,7        (5da table)
  122. f007    current lives p1
  123. f008    current lives p2
  124.  
  125. f009<-    coin/credit 1: dsw-1 & 0x30 index; values: 11,12,21,23    (5de table)
  126. f00a<-    coin 1
  127. f00b<-    coin/credit 2: dsw-1 & 0xc0 index; values: 11,12,21,23    (5e2 table)
  128. f00c<-    coin 2
  129.  
  130. f00f    ?? outa (28h)
  131. f010    written by sub cpu, bit 4 read by main cpu.
  132.         bit 0    p1 playing
  133.         bit 1    p2 playing
  134.  
  135. f014    index (1-f) of routine called during int 36e (table at c3f)
  136.     1:    62b            2:    66a            3:    6ad            4:    79f
  137.     5:    7e0            6:    81b            7:    8a7            8:    8e9
  138.     9:    b02            a:    0            b:    0            c:    bfc
  139.     d:    c0d            e:    a6f            f:    ac3
  140.  
  141. f015    index of the routine to call, usually the one selected by f014
  142.         but sometimes written directly.
  143.  
  144. Scroll registers: ports 04/06/08/0a/0c, written in sequence (101f)
  145. port 06 <- f100 + f140    x        port 04 <- f104 + f142    y
  146. port 0a <- f120 + f140    x        port 08 <- f124 + f142    y
  147. port 0c <- f14c = bit 0/1/2/3 = port 6/4/a/8 val < FF
  148.  
  149. f148->    sound code (from main cpu)
  150. f14c    scroll regs high bits
  151.  
  152. ----------------
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.                     Interesting routines (sound cpu)
  162.                     -------------------------------
  163.  
  164. 50a        6295
  165. 521        6295
  166. a96        2203 reg<-B        val<-A
  167.  
  168.                     Interesting locations (sound cpu)
  169.                     ---------------------------------
  170.  
  171. c715
  172. c716    pending sound command
  173. c760    rom bank
  174.  
  175.  
  176.                                 To Do
  177.                                 -----
  178.  
  179. - The bankswitching registers bits 4&5 are used (any Z80). What for ?
  180. - Is the sub cpu / sound cpu communication status port (0e) correct ?
  181. - Main cpu: port  01 ?
  182. - Sub  cpu: ports 0x28, 0x38 ? Plus it can probably cause a nmi to main cpu
  183. - incomplete DSW's
  184. - Spriteram low 0x300 bytes (priority?)
  185.  
  186. ***************************************************************************/
  187.  
  188. #include "driver.h"
  189. #include "cpu/z80/z80.h"
  190.  
  191. unsigned char *devram, *sharedram;
  192. int soundlatch_status, soundlatch2_status;
  193.  
  194. /* Variables that vidhrdw has access to */
  195. extern unsigned char *spriteram;
  196. int flipscreen;
  197.  
  198. /* Variables defined in vidhrdw */
  199. extern unsigned char *airbustr_bgram, *airbustr_fgram;
  200.  
  201. /* Functions defined in vidhrdw */
  202. WRITE_HANDLER( airbustr_bgram_w );
  203. WRITE_HANDLER( airbustr_fgram_w );
  204. WRITE_HANDLER( airbustr_scrollregs_w );
  205. extern int  airbustr_vh_start(void);
  206. extern void airbustr_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
  207.  
  208. /* Debug stuff (bound to go away sometime) */
  209. int u1, u2, u3, u4;
  210.  
  211.  
  212. static WRITE_HANDLER( bankswitch_w );
  213. static WRITE_HANDLER( bankswitch2_w );
  214. static WRITE_HANDLER( sound_bankswitch_w );
  215.  
  216. static void airbustr_init_machine (void)
  217. {
  218.     soundlatch_status = soundlatch2_status = 0;
  219.     bankswitch_w(0,2);
  220.     bankswitch2_w(0,2);
  221.     sound_bankswitch_w(0,2);
  222. }
  223.  
  224.  
  225. /*
  226. **
  227. **                Main cpu data
  228. **
  229. */
  230.  
  231. /*    Runs in IM 2    fd-fe    address of int: 0x38
  232.                     ff-100    address of int: 0x16    */
  233.  
  234. int airbustr_interrupt(void)
  235. {
  236. static int addr = 0xff;
  237.  
  238.     addr ^= 0x02;
  239.  
  240.     return addr;
  241. }
  242.  
  243.  
  244. static READ_HANDLER( sharedram_r )    { return sharedram[offset]; }
  245. static WRITE_HANDLER( sharedram_w )    { sharedram[offset] = data; }
  246.  
  247.  
  248. /* There's an MCU here, possibly */
  249. READ_HANDLER( devram_r )
  250. {
  251.     switch (offset)
  252.     {
  253.         /* Reading efe0 probably resets a watchdog mechanism
  254.            that would reset the main cpu. We avoid this and patch
  255.            the rom instead (main cpu has to be reset once at startup) */
  256.         case 0xfe0:
  257.             return 0/*watchdog_reset_r(0)*/;
  258.             break;
  259.  
  260.         /* Reading a word at eff2 probably yelds the product
  261.               of the words written to eff0 and eff2 */
  262.         case 0xff2:
  263.         case 0xff3:
  264.         {
  265.             int    x = (devram[0xff0] + devram[0xff1] * 256) *
  266.                     (devram[0xff2] + devram[0xff3] * 256);
  267.             if (offset == 0xff2)    return (x & 0x00FF) >> 0;
  268.             else                return (x & 0xFF00) >> 8;
  269.         }    break;
  270.  
  271.         /* Reading eff4, F0 times must yield at most 80-1 consecutive
  272.            equal values */
  273.         case 0xff4:
  274.         {
  275.             return rand();
  276.         }    break;
  277.  
  278.         default:    { return devram[offset]; break;}
  279.     }
  280.  
  281. }
  282. WRITE_HANDLER( devram_w )    {    devram[offset] = data; }
  283.  
  284.  
  285. static WRITE_HANDLER( bankswitch_w )
  286. {
  287. unsigned char *RAM = memory_region(REGION_CPU1);
  288.  
  289.     if ((data & 7) <  3)    RAM = &RAM[0x4000 * (data & 7)];
  290.     else                    RAM = &RAM[0x10000 + 0x4000 * ((data & 7)-3)];
  291.  
  292.     cpu_setbank(1,RAM);
  293. //    if (data > 7)    logerror("CPU #0 - suspicious bank: %d ! - PC = %04X\n", data, cpu_get_pc());
  294.  
  295.     u1 = data & 0xf8;
  296. }
  297.  
  298. /* Memory */
  299.  
  300. static struct MemoryReadAddress readmem[] =
  301. {
  302.     { 0x0000, 0x7fff, MRA_ROM },
  303.     { 0x8000, 0xbfff, MRA_BANK1 },
  304.     { 0xc000, 0xcfff, MRA_RAM },
  305.     { 0xd000, 0xdfff, MRA_RAM },
  306.     { 0xe000, 0xefff, devram_r },
  307.     { 0xf000, 0xffff, sharedram_r },
  308.     { -1 }
  309. };
  310. static struct MemoryWriteAddress writemem[] =
  311. {
  312.     { 0x0000, 0xbfff, MWA_ROM },    // writing at 0 should cause a reset
  313.     { 0xc000, 0xcfff, MWA_RAM, &spriteram },            // RAM 0/1
  314.     { 0xd000, 0xdfff, MWA_RAM },                        // RAM 2
  315.     { 0xe000, 0xefff, devram_w, &devram },                // RAM 3
  316.     { 0xf000, 0xffff, sharedram_w, &sharedram },
  317.     { -1 }
  318. };
  319.  
  320. /* Ports */
  321.  
  322. static WRITE_HANDLER( cause_nmi_w )
  323. {
  324.     cpu_cause_interrupt(1,Z80_NMI_INT);    // cause a nmi to sub cpu
  325. }
  326.  
  327. static struct IOReadPort readport[] =
  328. {
  329.     { -1 }
  330. };
  331. static struct IOWritePort writeport[] =
  332. {
  333.     { 0x00, 0x00, bankswitch_w },
  334. //    { 0x01, 0x01, IOWP_NOP },    // ?? only 2 (see 378b)
  335.     { 0x02, 0x02, cause_nmi_w },    // always 0. Cause a nmi to sub cpu
  336.     { -1 }
  337. };
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348. /*
  349. **
  350. **                Sub cpu data
  351. **
  352. **
  353. */
  354.  
  355. /*    Runs in IM 2    fd-fe    address of int: 0x36e    (same as 0x38)
  356.                     ff-100    address of int: 0x4b0    (only writes to port 38h)    */
  357.  
  358. int airbustr_interrupt2(void)
  359. {
  360. static int addr = 0xfd;
  361.  
  362.     addr ^= 0x02;
  363.  
  364.     return addr;
  365. }
  366.  
  367.  
  368. static WRITE_HANDLER( bankswitch2_w )
  369. {
  370. unsigned char *RAM = memory_region(REGION_CPU2);
  371.  
  372.     if ((data & 7) <  3)    RAM = &RAM[0x4000 * (data & 7)];
  373.     else                    RAM = &RAM[0x10000 + 0x4000 * ((data & 7)-3)];
  374.  
  375.     cpu_setbank(2,RAM);
  376. //    if (data > 7)    logerror("CPU #1 - suspicious bank: %d ! - PC = %04X\n", data, cpu_get_pc());
  377.  
  378.     flipscreen = data & 0x10;    // probably..
  379.     tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
  380.  
  381.     u2 = data & 0xf8;
  382. }
  383.  
  384.  
  385. WRITE_HANDLER( airbustr_paletteram_w )
  386. {
  387. int r,g,b;
  388.  
  389.     /*    ! byte 1 ! ! byte 0 !    */
  390.     /*    xGGG GGRR     RRRB BBBB    */
  391.     /*    x432 1043     2104 3210    */
  392.  
  393.     paletteram[offset] = data;
  394.     data = (paletteram[offset | 1] << 8) | paletteram[offset & ~1];
  395.  
  396.     g = (data >> 10) & 0x1f;
  397.     r = (data >>  5) & 0x1f;
  398.     b = (data >>  0) & 0x1f;
  399.  
  400.     palette_change_color(offset/2,    (r * 0xff) / 0x1f,
  401.                                     (g * 0xff) / 0x1f,
  402.                                     (b * 0xff) / 0x1f );
  403. }
  404.  
  405.  
  406. /* Memory */
  407.  
  408. static struct MemoryReadAddress readmem2[] =
  409. {
  410.     { 0x0000, 0x7fff, MRA_ROM },
  411.     { 0x8000, 0xbfff, MRA_BANK2 },
  412.     { 0xc000, 0xcfff, MRA_RAM },
  413.     { 0xd000, 0xd5ff, paletteram_r },
  414.     { 0xd600, 0xdfff, MRA_RAM },
  415.     { 0xe000, 0xefff, MRA_RAM },
  416.     { 0xf000, 0xffff, sharedram_r },
  417.     { -1 }
  418. };
  419.  
  420. static struct MemoryWriteAddress writemem2[] =
  421. {
  422.     { 0x0000, 0xbfff, MWA_ROM },
  423.     { 0xc000, 0xc7ff, airbustr_fgram_w, &airbustr_fgram },
  424.     { 0xc800, 0xcfff, airbustr_bgram_w, &airbustr_bgram },
  425.     { 0xd000, 0xd5ff, airbustr_paletteram_w, &paletteram },
  426.     { 0xd600, 0xdfff, MWA_RAM },
  427.     { 0xe000, 0xefff, MWA_RAM },
  428.     { 0xf000, 0xffff, sharedram_w },
  429.     { -1 }
  430. };
  431.  
  432.  
  433. /* Ports */
  434.  
  435. /*
  436.    Sub cpu and Sound cpu communicate bidirectionally:
  437.  
  438.        Sub   cpu writes to soundlatch,  reads from soundlatch2
  439.        Sound cpu writes to soundlatch2, reads from soundlatch
  440.  
  441.    Each latch raises a flag when it's been written.
  442.    The flag is cleared when the latch is read.
  443.  
  444. Code at 505: waits for bit 1 to go low, writes command, waits for bit
  445. 0 to go low, reads back value. Code at 3b2 waits bit 2 to go high
  446. (called during int fd)
  447.  
  448. */
  449.  
  450.  
  451. static READ_HANDLER( soundcommand_status_r )
  452. {
  453. /* bits: 2 <-> ?    1 <-> soundlatch full    0 <-> soundlatch2 empty */
  454.     return 4 + soundlatch_status * 2 + (1-soundlatch2_status);
  455. }
  456.  
  457.  
  458. static READ_HANDLER( soundcommand2_r )
  459. {
  460.     soundlatch2_status = 0;                // soundlatch2 has been read
  461.     return soundlatch2_r(0);
  462. }
  463.  
  464.  
  465. static WRITE_HANDLER( soundcommand_w )
  466. {
  467.     soundlatch_w(0,data);
  468.     soundlatch_status = 1;                // soundlatch has been written
  469.     cpu_cause_interrupt(2,Z80_NMI_INT);    // cause a nmi to sub cpu
  470. }
  471.  
  472.  
  473. WRITE_HANDLER( port_38_w )    {    u4 = data; } // for debug
  474.  
  475.  
  476. static struct IOReadPort readport2[] =
  477. {
  478.     { 0x02, 0x02, soundcommand2_r },        // from sound cpu
  479.     { 0x0e, 0x0e, soundcommand_status_r },    // status of the latches ?
  480.     { 0x20, 0x20, input_port_0_r },            // player 1
  481.     { 0x22, 0x22, input_port_1_r },            // player 2
  482.     { 0x24, 0x24, input_port_2_r },            // service
  483.     { -1 }
  484. };
  485.  
  486. static struct IOWritePort writeport2[] =
  487. {
  488.     { 0x00, 0x00, bankswitch2_w },            // bits 2-0 bank; bit 4 (on if dsw1-1 active)? ; bit 5?
  489.     { 0x02, 0x02, soundcommand_w },            // to sound cpu
  490.     { 0x04, 0x0c, airbustr_scrollregs_w },    // Scroll values
  491. //    { 0x28, 0x28, port_38_w },                // ??
  492. //    { 0x38, 0x38, IOWP_NOP },                // ?? Followed by EI. Value isn't important
  493.     { -1 }
  494. };
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505. /*
  506. **
  507. **                 Sound cpu data
  508. **
  509. */
  510.  
  511. static WRITE_HANDLER( sound_bankswitch_w )
  512. {
  513. unsigned char *RAM = memory_region(REGION_CPU3);
  514.  
  515.     if ((data & 7) <  3)    RAM = &RAM[0x4000 * (data & 7)];
  516.     else                    RAM = &RAM[0x10000 + 0x4000 * ((data & 7)-3)];
  517.  
  518.     cpu_setbank(3,RAM);
  519. //    if (data > 7)    logerror("CPU #2 - suspicious bank: %d ! - PC = %04X\n", data, cpu_get_pc());
  520.  
  521.     u3 = data & 0xf8;
  522. }
  523.  
  524.  
  525. /* Memory */
  526.  
  527. static struct MemoryReadAddress sound_readmem[] =
  528. {
  529.     { 0x0000, 0x7fff, MRA_ROM },
  530.     { 0x8000, 0xbfff, MRA_BANK3 },
  531.     { 0xc000, 0xdfff, MRA_RAM },
  532.     { -1 }
  533. };
  534.  
  535. static struct MemoryWriteAddress sound_writemem[] =
  536. {
  537.     { 0x0000, 0xbfff, MWA_ROM },
  538.     { 0xc000, 0xdfff, MWA_RAM },
  539.     { -1 }
  540. };
  541.  
  542.  
  543. /* Ports */
  544.  
  545. READ_HANDLER( soundcommand_r )
  546. {
  547.     soundlatch_status = 0;        // soundlatch has been read
  548.     return soundlatch_r(0);
  549. }
  550.  
  551.  
  552. WRITE_HANDLER( soundcommand2_w )
  553. {
  554.     soundlatch2_status = 1;        // soundlatch2 has been written
  555.     soundlatch2_w(0,data);
  556. }
  557.  
  558.  
  559. static struct IOReadPort sound_readport[] =
  560. {
  561.     { 0x02, 0x02, YM2203_status_port_0_r },
  562.     { 0x03, 0x03, YM2203_read_port_0_r },
  563.     { 0x04, 0x04, OKIM6295_status_0_r },
  564.     { 0x06, 0x06, soundcommand_r },            // read command from sub cpu
  565.     { -1 }
  566. };
  567.  
  568. static struct IOWritePort sound_writeport[] =
  569. {
  570.     { 0x00, 0x00, sound_bankswitch_w },
  571.     { 0x02, 0x02, YM2203_control_port_0_w },
  572.     { 0x03, 0x03, YM2203_write_port_0_w },
  573.     { 0x04, 0x04, OKIM6295_data_0_w },
  574.     { 0x06, 0x06, soundcommand2_w },        // write command result to sub cpu
  575.     { -1 }
  576. };
  577.  
  578.  
  579.  
  580.  
  581. /*    Input Ports:
  582.     [0] Player 1        [1] Player 2
  583.     [2] Service
  584.     [3] Dsw 1            [4] Dsw 2    */
  585.  
  586. INPUT_PORTS_START( airbustr )
  587.  
  588.     PORT_START    // IN0 - Player 1
  589.     PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY )
  590.     PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY )
  591.     PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY )
  592.     PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY )
  593.     PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
  594.     PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
  595.     PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
  596.     PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
  597.  
  598.     PORT_START    // IN1 - Player 2
  599.     PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY | IPF_PLAYER2 )
  600.     PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY | IPF_PLAYER2 )
  601.     PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY | IPF_PLAYER2 )
  602.     PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER2 )
  603.     PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
  604.     PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
  605.     PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
  606.     PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
  607.  
  608.     PORT_START    // IN2 - Service
  609.     PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
  610.     PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
  611.     PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN1 )
  612.     PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN2 )
  613.     PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
  614.     PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
  615.     PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN3 )
  616.     PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )    // used
  617.  
  618.     PORT_START    // IN3 - DSW-1
  619.     PORT_DIPNAME( 0x01, 0x01, "Unknown 1-0" )
  620.     PORT_DIPSETTING(    0x01, DEF_STR( Off ) )
  621.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  622.     PORT_DIPNAME( 0x02, 0x02, DEF_STR( Flip_Screen ) )    // if active, bit 4 of cpu2 bank is on ..
  623.     PORT_DIPSETTING(    0x02, DEF_STR( Off ) )            // is this a flip screen?
  624.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )            // it changes the scroll offsets
  625.     PORT_SERVICE( 0x04, IP_ACTIVE_LOW )
  626.     PORT_DIPNAME( 0x08, 0x08, "Unknown 1-3" )        //    routine 56d:    11 21 12 16 (bit 3 active)
  627.     PORT_DIPSETTING(    0x08, DEF_STR( Off ) )        //                    11 21 13 14 (bit 3 not active)
  628.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  629.     PORT_DIPNAME( 0x30, 0x30, DEF_STR( Coin_A ) )    //    routine 546:    11 12 21 23
  630.     PORT_DIPSETTING(    0x10, DEF_STR( 2C_1C ) )
  631.     PORT_DIPSETTING(    0x30, DEF_STR( 1C_1C ) )
  632.     PORT_DIPSETTING(    0x00, DEF_STR( 2C_3C ) )
  633.     PORT_DIPSETTING(    0x20, DEF_STR( 1C_2C ) )
  634.     PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Coin_B ) )
  635.     PORT_DIPSETTING(    0x40, DEF_STR( 2C_1C ) )
  636.     PORT_DIPSETTING(    0xc0, DEF_STR( 1C_1C ) )
  637.     PORT_DIPSETTING(    0x00, DEF_STR( 2C_3C ) )
  638.     PORT_DIPSETTING(    0x80, DEF_STR( 1C_2C ) )
  639.  
  640.     PORT_START    // IN4 - DSW-2
  641.     PORT_DIPNAME( 0x03, 0x03, DEF_STR( Difficulty ) )
  642.     PORT_DIPSETTING(    0x02, "Easy" )
  643.     PORT_DIPSETTING(    0x03, "Normal" )
  644.     PORT_DIPSETTING(    0x01, "Hard" )
  645.     PORT_DIPSETTING(    0x00, "Hardest" )
  646.     PORT_DIPNAME( 0x04, 0x04, "Unknown 2-2" )
  647.     PORT_DIPSETTING(    0x04, DEF_STR( Off ) )
  648.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  649.     PORT_DIPNAME( 0x08, 0x08, "Freeze" )
  650.     PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
  651.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  652.     PORT_DIPNAME( 0x30, 0x30, DEF_STR( Lives ) )
  653.     PORT_DIPSETTING(    0x30, "3" )
  654.     PORT_DIPSETTING(    0x20, "4" )
  655.     PORT_DIPSETTING(    0x10, "5" )
  656.     PORT_DIPSETTING(    0x00, "7" )
  657.     PORT_DIPNAME( 0x40, 0x40, DEF_STR( Demo_Sounds ) )
  658.     PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
  659.     PORT_DIPSETTING(    0x40, DEF_STR( On ) )
  660.     PORT_DIPNAME( 0x80, 0x80, "Unknown 2-7" )
  661.     PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
  662.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  663.  
  664. INPUT_PORTS_END
  665.  
  666.  
  667.  
  668. /*
  669. **
  670. **                 Gfx data
  671. **
  672. */
  673.  
  674.  
  675. /* displacement in bits to lower part of gfx */
  676. #define lo (8*8*4*2)
  677. #define layout16x16(_name_,_romsize_) \
  678. static struct GfxLayout _name_ =\
  679. {\
  680.     16,16,\
  681.     (_romsize_)*8/(16*16*4),\
  682.     4,\
  683.     {0, 1, 2, 3},\
  684.     {0*4,1*4,2*4,3*4,4*4,5*4,6*4,7*4, \
  685.      0*4+32*8,1*4+32*8,2*4+32*8,3*4+32*8,4*4+32*8,5*4+32*8,6*4+32*8,7*4+32*8},\
  686.     {0*32,1*32,2*32,3*32,4*32,5*32,6*32,7*32,\
  687.      0*32+lo,1*32+lo,2*32+lo,3*32+lo,4*32+lo,5*32+lo,6*32+lo,7*32+lo}, \
  688.     16*16*4\
  689. };
  690.  
  691. layout16x16(tilelayout,  0x080000)
  692. layout16x16(spritelayout,0x100000)
  693.  
  694. static struct GfxDecodeInfo gfxdecodeinfo[] =
  695. {
  696.     { REGION_GFX1, 0, &tilelayout,   256*0, (256*2) / 16 }, // [0] Layers
  697.     { REGION_GFX2, 0, &spritelayout, 256*2, (256*1) / 16 }, // [1] Sprites
  698.     { -1 }
  699. };
  700.  
  701.  
  702.  
  703. static struct YM2203interface ym2203_interface =
  704. {
  705.     1,
  706.     3000000,                    /* ?? */
  707.     { YM2203_VOL(0xff,0xff) },    /* gain,volume */
  708.     { input_port_3_r },            /* DSW-1 connected to port A */
  709.     { input_port_4_r },            /* DSW-2 connected to port B */
  710.     { 0 },
  711.     { 0 },
  712.     { 0 }
  713. };
  714.  
  715. static struct OKIM6295interface okim6295_interface =
  716. {
  717.     1,
  718.     { 18000 },        /* ?? */
  719.     { REGION_SOUND1 },
  720.     { 50 }
  721. };
  722.  
  723.  
  724. static struct MachineDriver machine_driver_airbustr =
  725. {
  726.     {
  727.         {
  728.             CPU_Z80,
  729.             6000000,    /* ?? */
  730.             readmem,writemem,readport,writeport,
  731.             airbustr_interrupt, 2    /* nmi caused by sub cpu?, ? */
  732.         },
  733.         {
  734.             CPU_Z80,
  735.             6000000,    /* ?? */
  736.             readmem2,writemem2,readport2,writeport2,
  737.             airbustr_interrupt2, 2    /* nmi caused by main cpu, ? */
  738.         },
  739.         {
  740.             CPU_Z80,    /* Sound CPU, reads DSWs. Hence it can't be disabled */
  741.             6000000,    /* ?? */
  742.             sound_readmem,sound_writemem,sound_readport,sound_writeport,
  743.             interrupt,1    /* nmi are caused by sub cpu writing a sound command */
  744.         },
  745.     },
  746.     60,DEFAULT_60HZ_VBLANK_DURATION,
  747.     100,    /* Palette RAM is filled by sub cpu with data supplied by main cpu */
  748.             /* Maybe an high value is safer in order to avoid glitches */
  749.     airbustr_init_machine,
  750.  
  751.     /* video hardware */
  752.     256, 256, { 0, 256-1, 0+16, 256-16-1 },
  753.     gfxdecodeinfo,
  754.     256 * 3, 256 * 3,
  755.     0,
  756.     VIDEO_TYPE_RASTER | VIDEO_MODIFIES_PALETTE,
  757.     0,
  758.     airbustr_vh_start,
  759.     0,
  760.     airbustr_vh_screenrefresh,
  761.  
  762.     /* sound hardware */
  763.     0,0,0,0,
  764.     {
  765.         {
  766.             SOUND_YM2203,
  767.             &ym2203_interface
  768.         },
  769.         {
  770.             SOUND_OKIM6295,
  771.             &okim6295_interface
  772.         }
  773.     }
  774. };
  775.  
  776.  
  777.  
  778. /***************************************************************************
  779.  
  780.   Game driver(s)
  781.  
  782. ***************************************************************************/
  783.  
  784. ROM_START( airbustr )
  785.     ROM_REGION( 0x24000, REGION_CPU1 )
  786.     ROM_LOAD( "pr-14j.bin", 0x00000, 0x0c000, 0x6b9805bd )
  787.     ROM_CONTINUE(           0x10000, 0x14000 )
  788.  
  789.     ROM_REGION( 0x24000, REGION_CPU2 )
  790.     ROM_LOAD( "pr-11j.bin", 0x00000, 0x0c000, 0x85464124 )
  791.     ROM_CONTINUE(           0x10000, 0x14000 )
  792.  
  793.     ROM_REGION( 0x24000, REGION_CPU3 )
  794.     ROM_LOAD( "pr-21.bin",  0x00000, 0x0c000, 0x6e0a5df0 )
  795.     ROM_CONTINUE(           0x10000, 0x14000 )
  796.  
  797.     ROM_REGION( 0x080000, REGION_GFX1 | REGIONFLAG_DISPOSE )
  798.     ROM_LOAD( "pr-000.bin", 0x000000, 0x80000, 0x8ca68f0d ) // scrolling layers
  799.  
  800.     ROM_REGION( 0x100000, REGION_GFX2 | REGIONFLAG_DISPOSE )
  801.     ROM_LOAD( "pr-001.bin", 0x000000, 0x80000, 0x7e6cb377 ) // sprites
  802.     ROM_LOAD( "pr-02.bin",  0x080000, 0x10000, 0x6bbd5e46 )
  803.  
  804.     ROM_REGION( 0x40000, REGION_SOUND1 )    /* OKI-M6295 samples */
  805.     ROM_LOAD( "pr-200.bin", 0x00000, 0x40000, 0xa4dd3390 )
  806. ROM_END
  807.  
  808.  
  809.  
  810. void init_airbustr(void)
  811. {
  812. int i;
  813. unsigned char *RAM;
  814.  
  815.     /* One gfx rom seems to have scrambled data (bad read?): */
  816.     /* let's swap even and odd nibbles */
  817.     RAM = memory_region(REGION_GFX1) + 0x000000;
  818.     for (i = 0; i < 0x80000; i ++)
  819.     {
  820.         RAM[i] = ((RAM[i] & 0xF0)>>4) + ((RAM[i] & 0x0F)<<4);
  821.     }
  822.  
  823.     RAM = memory_region(REGION_CPU1);
  824.     RAM[0x37f4] = 0x00;        RAM[0x37f5] = 0x00;    // startup check. We need a reset
  825.                                                 // so I patch a busy loop with jp 0
  826.  
  827.     RAM = memory_region(REGION_CPU2);
  828.     RAM[0x0258] = 0x53; // include EI in the busy loop.
  829.                         // It's an hack to repair nested nmi troubles
  830. }
  831.  
  832.  
  833.  
  834. GAME( 1990, airbustr, 0, airbustr, airbustr, airbustr, ROT0, "Kaneko (Namco license)", "Air Buster (Japan)" )
  835.